﻿// -------------------------------------------------------------------------------------------------------------------------------
// <copyright file="RMDenseMatrix{T}.cs" company="Exul">
//     Copyright (c) Exul. All rights reserved.
// </copyright>
// <author>
//     Exul
// </author>
// -------------------------------------------------------------------------------------------------------------------------------

namespace ExulLibrary.Mathematics.LinearAlgebra
{
    #region Usings

    using System;

    using ExulLibrary.Exceptions;

    #endregion

    /// <summary>
    ///     Represents a dense matrix with row-major two-dimensional storage.
    /// </summary>
    /// <typeparam name="T">
    ///     The type of values of matrix elements.
    /// </typeparam>
    public sealed class RMDenseMatrix<T> : Matrix<T>
    {
        #region Fields

        #region private

        /// <summary>
        ///     The registration index that uniquely identify matrix type.
        /// </summary>
        private static readonly int RegistrationIndex = Global.GetMatrixRegistrationIndex(typeof(RMDenseMatrix<object>));

        #endregion

        #endregion

        #region Constructors and Destructors

        #region public

        /// <summary>
        ///     Initializes a new instance of the <see cref="RMDenseMatrix{T}"/> class.
        /// </summary>
        /// <param name="data">
        ///     The collection of values of matrix elements in row-major order.
        /// </param>
        /// <exception cref="ArgumentNullException">
        ///     <paramref name="data"/> is <see langword="null"/>.
        ///     <para>
        ///         --or--
        ///     </para>
        ///     <para>
        ///         The first element of <paramref name="data"/> is <see langword="null"/>.
        ///     </para>
        /// </exception>
        /// <exception cref="EmptyCollectionException">
        ///     <paramref name="data"/> is empty.
        ///     <para>
        ///         --or--
        ///     </para>
        ///     <para>
        ///         The first element of <paramref name="data"/> is empty.
        ///     </para>
        /// </exception>
        public RMDenseMatrix(T[][] data)
        {
            #if SAFE

            if (data == null)
            {
                throw new ArgumentNullException("data");
            }

            if (data.Length == 0)
            {
                throw new EmptyCollectionException("data");
            }

            if (data[0] == null)
            {
                throw new ArgumentNullException("data[0]");
            }

            if (data[0].Length == 0)
            {
                throw new EmptyCollectionException("data[0]");
            }

            #endif

            this.RowsCount = data.Length;
            this.ColumnsCount = data[0].Length;
            this.Values = data;
        }

        #endregion

        #endregion

        #region Properties

        #region public

        /// <summary>
        ///     Gets the collection of values of matrix elements in row-major order.
        /// </summary>
        /// <value>
        ///     The collection of values of matrix elements in row-major order.
        /// </value>
        public T[][] Values
        {
            get;
            private set;
        }

        #endregion

        #endregion

        #region Overridden Properties

        #region public

        /// <summary>
        ///     Gets the registration index of the matrix that uniquely identifies type of matrix.
        /// </summary>
        /// <value>
        ///     The registration index of the matrix that uniquely identifies type of matrix.
        /// </value>
        public override int MatrixRegistrationIndex
        {
            get
            {
                return RegistrationIndex;
            }
        }

        #endregion

        #endregion
    }
}